package com.heima.behavior.service.impl;

import com.heima.behavior.service.ApBehaviorEntryService;
import com.heima.common.exception.CustException;
import com.heima.model.behavior.pojos.ApBehaviorEntry;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Author XHui
 * @Since 2024/2/21 17:20
 * @Version 1.0
 */
@Service
public class ApBehaviorEntryServiceImpl implements ApBehaviorEntryService {

    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * 按用户 ID 或设备 ID 查找用户实体 ->
     *
     * @param userId      用户 ID
     * @param equipmentId 设备 ID
     * @return AP 行为条目
     */
    @Override
    public ApBehaviorEntry findByUserIdOrEquipmentId
    (Integer userId, Integer equipmentId) {

        ApBehaviorEntry apBehaviorEntry = new ApBehaviorEntry();
        apBehaviorEntry.setType(ApBehaviorEntry.Type.USER.getCode());
        apBehaviorEntry.setRefId(userId);
        apBehaviorEntry.setCreatedTime(new Date());

        // ApBehaviorEntry apBehaviorEntryResult = new ApBehaviorEntry();

        if (userId != null) {
            // 1. 根据用户 ID  行为条目
            ApBehaviorEntry behaviorEntryByUser = getBehaviorEntryByType(userId, ApBehaviorEntry.Type.USER.getCode());
            // 2. 若根据用户 ID 查询不到，就插入一条
            if (behaviorEntryByUser == null) {
                return mongoTemplate.insert(apBehaviorEntry);
            } else {
                return behaviorEntryByUser;
            }
        } else if (equipmentId != null) {
            // 3. 根据设备 ID 查询 AP
            apBehaviorEntry.setType(ApBehaviorEntry.Type.EQUIPMENT.getCode());
            apBehaviorEntry.setRefId(equipmentId);
            ApBehaviorEntry behaviorEntryByEquipment = getBehaviorEntryByType(equipmentId, ApBehaviorEntry.Type.EQUIPMENT.getCode());
            //  4. 若根据设备 ID 查询不到，就插入一条
            if (behaviorEntryByEquipment == null) {
                return mongoTemplate.insert(apBehaviorEntry);
            } else {
                return behaviorEntryByEquipment;
            }
        }
        //  5. 返回结果
        // 设备ID 和 用户ID都不存在，null
        return null;
    }


    private ApBehaviorEntry getBehaviorEntryByType
            (Integer entryId, Short type) {

        Criteria criteria = Criteria.where("refId").is(entryId);
        if (type == ApBehaviorEntry.Type.USER.getCode()) {
            criteria.and("type").is(ApBehaviorEntry.Type.USER.getCode());
        } else if (type == ApBehaviorEntry.Type.EQUIPMENT.getCode()) {
            criteria.and("type").is(ApBehaviorEntry.Type.EQUIPMENT.getCode());
        }

        Query query = Query.query(criteria);
        // 查询数据库
        return mongoTemplate.findOne(query, ApBehaviorEntry.class);
    }

    public <T> T findBehaviorTraceByEntryIdAndArticleId
            (Long articleId, Integer equipmentId, Class<T> entityClass) {

        ApBehaviorEntry apBehaviorEntryByRefId = getApBehaviorEntryByUserIdOrEquipmentId(equipmentId);

        String entryId = apBehaviorEntryByRefId.getId();

        // 3. 查询用户是否是首次阅读当前文章 by  entryId + articleId
        Query query = Query.query(
                Criteria.where("entryId").is(entryId)
                        .and("articleId").is(articleId)
        );
        T one = mongoTemplate.findOne(query, entityClass);
        return one;
    }

    public ApBehaviorEntry getApBehaviorEntryByUserIdOrEquipmentId(Integer equipmentId) {
        // 1. 获取当前登录用户信息
        ApUser user = AppThreadLocalUtils.getUser();

        // 2. 查询当前用户的行为实体
        ApBehaviorEntry apBehaviorEntryByRefId = null;
        if (user != null) {
            apBehaviorEntryByRefId = findByUserIdOrEquipmentId(user.getId(), null);
        } else {
            apBehaviorEntryByRefId = findByUserIdOrEquipmentId(null, equipmentId);
        }
        // 3. 查询不到行为实体，返回null
        if(apBehaviorEntryByRefId == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "未找到用户行为实体根据用户ID或者设备ID");
        }
        return apBehaviorEntryByRefId;
    }

}
